package controllers

import java.io.File
import java.nio.file.Files

import command.CommandExec
import dao.{DealDao, GroupDao, ProjectDao}
import javax.inject.Inject
import org.apache.commons.io.FileUtils
import play.api.libs.json.Json
import play.api.mvc._
import utils.Utils
import models.Tables._
import org.joda.time.DateTime
import tool.Pojo.CommandData
import tool.Tool

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

/**
  * Created by yz on 2018/6/11
  */
class ProjectController @Inject()(tool: Tool, projectDao: ProjectDao, formTool: FormTool, groupDao: GroupDao,
                                  dealDao: DealDao) extends Controller {

  def projectManageBefore = Action { implicit request =>
    Ok(views.html.user.projectManage())
  }

  def toIndex = Action { implicit request =>
    Redirect(routes.ProjectController.projectManageBefore())
  }

  def toHome = Action { implicit request =>
    val domain = tool.getRequestDomain
    Redirect(s"http://${domain}/project/platformHome")
  }

  def logout = Action { implicit request =>
    val domain = tool.getRequestDomain
    Redirect(s"http://${domain}/").flashing("info" -> "退出登录成功!").withNewSession
  }

  def getAllProject = Action.async { implicit request =>
    val userId = tool.getUserId
    projectDao.selectAll(userId).map { x =>
      val array = Utils.getArrayByTs(x)
      Ok(Json.toJson(array))
    }
  }

  def mock = Action { implicit request =>
    Redirect(routes.ProjectController.projectManageBefore()).withSession("id" -> "1", "user" -> "yz")
  }

  def projectNameCheck = Action.async { implicit request =>
    val data = formTool.projectNameForm.bindFromRequest.get
    val userId = tool.getUserId
    projectDao.selectByProjectName(userId, data.projectName).map {
      case Some(y) => Ok(Json.obj("valid" -> false))
      case None => Ok(Json.obj("valid" -> true))
    }
  }

  def addProject = Action.async(parse.multipartFormData) { implicit request =>
    val data = formTool.projectForm.bindFromRequest().get
    val userId = tool.getUserId
    val row = ProjectRow(0, userId, data.projectName, data.describe, new DateTime())
    val tmpDataFile = request.body.file("dataFile").get
    val tmpFile = Files.createTempFile("data", ".txt").toFile
    tmpDataFile.ref.moveTo(tmpFile, true)
    val (b, message) = Utils.checkFile(tmpFile)
    if (b) {
      projectDao.insertReturnId(row).map { x =>
        val id = x
        val userIdDir = new File(Tool.dataDir, userId.toString)
        Utils.createDirectoryWhenNoExist(userIdDir)
        val projectIdDir = new File(userIdDir, id.toString)
        Utils.createDirectoryWhenNoExist(projectIdDir)
        val dataFile = new File(projectIdDir, "data.txt")
        val dealFile = new File(projectIdDir, "deal.txt")
        FileUtils.copyFile(tmpFile, dataFile)
        FileUtils.copyFile(dataFile, dealFile)
        tmpFile.delete()

        CommandExec().exec { b =>
          val command =
            s"""
               |dos2unix *
               |""".stripMargin
          CommandData(projectIdDir, command)
        }

        Redirect(routes.ProjectController.getAllProject())
      }
    } else {
      tmpFile.delete()
      Future.successful(Ok(Json.obj("valid" -> "false", "message" -> message)))
    }
  }

  def deleteProjectByProjectId = Action.async { implicit request =>
    val data = formTool.projectIdForm.bindFromRequest().get
    val projectId = data.projectId
    groupDao.deleteByProjectId(projectId).zip(projectDao.deleteById(projectId)).zip(dealDao.deleteByProjectId(projectId)).
      map { x =>
        val projectIdDir = tool.getProjectIdDir(projectId)
        Utils.deleteDirectory(projectIdDir)
        val optionProjectId = tool.getOptionProjectId
        if (optionProjectId.isDefined && optionProjectId.get.toInt == projectId) {
          Redirect(routes.ProjectController.getAllProject()).removingFromSession(Tool.projectIdStr, Tool.projectNameStr)
        } else {
          Redirect(routes.ProjectController.getAllProject())
        }
      }
  }

  def delete(userId: Int) = Action.async { implicit request =>
    if (request.session.get("admin").isDefined && request.session.get("id").get == "1") {
      projectDao.selectAll(userId).flatMap { projects =>
        val projectIds = projects.map(_.id)
        dealDao.deleteByProjectIds(projectIds).zip(groupDao.deleteByProjectIds(projectIds))
      }.flatMap { x =>
        projectDao.deleteByUserId(userId)
      }.map { x =>
        val userIdDir = tool.getUserIdDir(userId)
        Utils.deleteDirectory(userIdDir)
        Ok("success!")
      }
    } else {
      Future.successful(Forbidden("Forbidden!"))
    }
  }


}
